{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "855d3b9e",
   "metadata": {},
   "source": [
    "# 第七讲 列表（一）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c4876e7e",
   "metadata": {},
   "source": [
    "在列表这一章节中，你将学习列表是什么以及如何使用列表元素。列表让你能够在一个地方存储成组的信息，其中既可以只包含几个元素，也可以包含数百万个元素。列表是新手可直接使用的最强大的Python功能之一，它融合了众多重要的编程概念。\n",
    "\n",
    "## 1. 列表是什么？\n",
    "\n",
    "### 1.1 列表的定义\n",
    "**列表（list）** 由一系列按特定顺序排列的元素组成。你不仅可以创建包含字母表中所有字母、数字0~9或所有家庭成员姓名的列表，还可以将任何东西加入列表，其中的元素之间可以没有任何关系。\n",
    "\n",
    "\n",
    "### 1.2 列表的特点 \n",
    "1. **有序**：列表中的元素按照添加的顺序进行存储。\n",
    "2. **可变性**：列表是可变的，这意味着你可以在创建列表后添加、删除或修改元素。\n",
    "3. **异构性**：列表可以包含不同类型的元素，例如整数、浮点数、字符串、甚至其他列表。\n",
    "4. **可迭代性**：列表是可迭代的，这意味着你可以使用循环来遍历列表中的元素。\n",
    "\n",
    "在Python中，用方括号（[]）表示列表，用逗号分隔其中的元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "76acb152",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['trek', 'cannondale', 'redline', 'specialized']\n"
     ]
    }
   ],
   "source": [
    "# bicycles.py\n",
    "bicycles = ['trek', 'cannondale', 'redline', 'specialized']\n",
    "print(bicycles)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c51a65a",
   "metadata": {},
   "source": [
    "## 2. 访问列表元素\n",
    "- 访问机制：列表是有序集合，因此要访问列表的任何元素，只需将该元素的位置（索引）告诉Python即可。\n",
    "- 访问语法：要访问列表元素，可指出列表的名称，再指出元素的索引，并将后者放在方括号内。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c5181ded",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "trek\n",
      "cannondale\n"
     ]
    }
   ],
   "source": [
    "bicycles = ['trek', 'cannondale', 'redline', 'specialized']\n",
    "print(bicycles[0])  # 访问第一个元素\n",
    "print(bicycles[1])  # 访问第二个元素"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26a69631",
   "metadata": {},
   "source": [
    "- 字符串方法的应用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "2c9dd4bc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Trek\n"
     ]
    }
   ],
   "source": [
    "bicycles = ['trek', 'cannondale', 'redline', 'specialized']\n",
    "print(bicycles[0].title())  # 首字母大写"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dbc67d5c",
   "metadata": {},
   "source": [
    "## 3. 索引从0而不是1开始\n",
    "\n",
    "### 3.1 重要概念\n",
    "\n",
    "- 在Python中，第一个列表元素的索引为0，而不是1\n",
    "- 大多数编程语言是如此规定的，这与列表操作的底层实现有关\n",
    "- 如果结果出乎意料，问问自己是否犯了简单而常见的差一错误\n",
    "\n",
    "### 3.2 索引对应关系\n",
    "\n",
    "| 元素位置   | 索引值 | 示例        |\n",
    "| ---------- | ------ | ----------- |\n",
    "| 第一个元素 | 0      | bicycles[0] |\n",
    "| 第二个元素 | 1      | bicycles[1] |\n",
    "| 第三个元素 | 2      | bicycles[2] |\n",
    "| 第四个元素 | 3      | bicycles[3] |\n",
    "\n",
    "### 3.3 负数索引  \n",
    "- 负数索引返回距离列表末尾相应距离的元素\n",
    "- 例如，索引-1返回最后一个元素，索引-2返回倒数第二个元素，以此类推\n",
    "\n",
    "| 索引值 | 对应元素       |\n",
    "| ------ | -------------- |\n",
    "| -1     | 最后一个元素   |\n",
    "| -2     | 倒数第二个元素 |\n",
    "| -3     | 倒数第三个元素 |\n",
    "\n",
    "\n",
    "### 3.4 使用列表中的各个值\n",
    "你可以像使用其他变量一样使用列表中的各个值。例如，可以使用f字符串根据列表中的值来创建消息。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4d92b5ee",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "My first bicycle was a Trek.\n"
     ]
    }
   ],
   "source": [
    "bicycles = ['trek', 'cannondale', 'redline', 'specialized']\n",
    "message = f\"My first bicycle was a {bicycles[0].title()}.\"\n",
    "print(message)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51c5f7ae",
   "metadata": {},
   "source": [
    "## 4. 修改、添加和删除元素\n",
    "### 4.1 动态列表概念\n",
    "- 列表是一种动态数据结构，这意味着你可以在创建列表后对其进行修改、添加和删除元素。\n",
    "- 这使得列表非常灵活，能够适应不同的需求。\n",
    "\n",
    "例如，你可能创建了一个游戏，要求玩家消灭从天而降的外星人：\n",
    "- 开始时将一些外星人存储在列表中\n",
    "- 每当有外星人被消灭时，都将其从列表中删除\n",
    "- 每次有新的外星人出现在屏幕上时，都将其添加到列表中\n",
    "- 在整个游戏运行期间，外星人列表的长度将不断变化\n",
    "- 游戏结束时，你可能需要打印出玩家消灭了多少个外星人"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a01814d2",
   "metadata": {},
   "source": [
    "### 4.2 修改列表元素\n",
    "- 要修改列表元素，需要指定列表名和要修改的元素的索引\n",
    "- 然后，给该元素指定新值\n",
    "- 你可以修改任意列表元素的值，而不只是第一个元素的值\n",
    "- 修改操作不会影响其他元素的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "15b0b187",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['honda', 'yamaha', 'suzuki']\n",
      "['ducati', 'yamaha', 'suzuki']\n"
     ]
    }
   ],
   "source": [
    "motorcycles = ['honda', 'yamaha', 'suzuki']\n",
    "print(motorcycles)\n",
    "\n",
    "motorcycles[0] = 'ducati'\n",
    "print(motorcycles)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b80fb368",
   "metadata": {},
   "source": [
    "### 4.3 在列表中添加元素\n",
    "\n",
    "你可能会出于很多原因在列表中添加新元素：\n",
    "\n",
    "- 游戏中出现新的外星人\n",
    "- 添加可视化数据\n",
    "- 给网站添加新注册的用户\n",
    "\n",
    "Python提供了多种在既有列表中添加新数据的方式。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c268162d",
   "metadata": {},
   "source": [
    "#### (1) append() 方法 - 在列表末尾添加元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b2ea8301",
   "metadata": {},
   "outputs": [],
   "source": [
    "motorcycles = ['honda', 'yamaha', 'suzuki']\n",
    "print(motorcycles)\n",
    "\n",
    "motorcycles.append('ducati')\n",
    "print(motorcycles)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "2c685ab9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['honda', 'yamaha', 'suzuki']\n",
      "['honda', 'yamaha', 'suzuki', 'ducati']\n"
     ]
    }
   ],
   "source": [
    "# 动态创建列表\n",
    "motorcycles = []\n",
    "motorcycles.append('honda')\n",
    "motorcycles.append('yamaha')\n",
    "motorcycles.append('suzuki')\n",
    "print(motorcycles)\n",
    "motorcycles.append('ducati')\n",
    "print(motorcycles)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92c23815",
   "metadata": {},
   "source": [
    "> 实际应用场景：这种创建列表的方式极其常见，因为经常要等程序运行后，你才知道用户要在程序中存储哪些数据。为了便于管理，可首先创建一个空列表，用于存储用户将要输入的值，然后将用户提供的每个新值追加到列表末尾。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73bd6dd8",
   "metadata": {},
   "source": [
    "#### (2) insert() 方法 - 在列表中插入元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "d32bcd1e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['ducati', 'honda', 'yamaha', 'suzuki']\n",
      "['ducati', 'honda', 'harley', 'yamaha', 'suzuki']\n"
     ]
    }
   ],
   "source": [
    "motorcycles = ['honda', 'yamaha', 'suzuki']\n",
    "\n",
    "motorcycles.insert(0, 'ducati')  # 在索引0处插入\n",
    "print(motorcycles)\n",
    "motorcycles.insert(2, 'harley')  # 在索引2处插入\n",
    "print(motorcycles)      "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af3fbf9f",
   "metadata": {},
   "source": [
    "插入机制：\n",
    "- 当你使用 insert() 方法在列表中插入元素时，Python 会将列表中索引为该位置的元素以及后面的所有元素都向右移动一个位置。\n",
    "- 这意味着插入操作会占用列表中的一个索引位置，而其他元素的索引会相应地增加。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a82464ba",
   "metadata": {},
   "source": [
    "### 4.4 从列表中删除元素\n",
    "你经常需要从列表中删除一个或多个元素：\n",
    "\n",
    "- 玩家将一个外星人消灭后，你很可能要将其从存活的外星人列表中删除\n",
    "- 当用户在你创建的Web应用程序中注销账户时，你需要将该用户从活动用户列表中删除\n",
    "\n",
    "你可以根据位置或值来删除列表中的元素。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8dd69b37",
   "metadata": {},
   "source": [
    "#### (1) del 语句 - 删除列表元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a783d0ac",
   "metadata": {},
   "outputs": [],
   "source": [
    "motorcycles = ['honda', 'yamaha', 'suzuki']\n",
    "print(motorcycles)\n",
    "\n",
    "del motorcycles[0]  # 删除第一个元素\n",
    "print(motorcycles)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b8607c97",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['honda', 'yamaha', 'suzuki']\n",
      "['honda', 'suzuki']\n"
     ]
    }
   ],
   "source": [
    "# 使用del可删除任意位置的列表元素，只需要知道其索引即可：\n",
    "motorcycles = ['honda', 'yamaha', 'suzuki']\n",
    "print(motorcycles)  \n",
    "del motorcycles[1]  # 删除索引1处的元素\n",
    "print(motorcycles)    \n",
    "\n",
    "# 使用del语句将值从列表中删除后，你就无法再访问它了。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd3dfb9e",
   "metadata": {},
   "source": [
    "#### (2) pop() 方法 - 删除列表元素\n",
    "有时候，你要将元素从列表中删除，并接着使用它的值。例如：\n",
    "\n",
    "- 你可能要获取刚被消灭的外星人的x坐标和y坐标，以便在相应的位置显示爆炸效果\n",
    "- 在Web应用程序中，你可能要将用户从活动成员列表中删除，并将其加入非活动成员列表\n",
    "\n",
    "pop()工作原理\n",
    "\n",
    "- pop()方法删除列表末尾的元素，并让你能够接着使用它\n",
    "- 术语弹出（pop）源自这样的类比：列表就像一个栈，而删除列表末尾的元素相当于弹出栈顶元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c5f276a4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['honda', 'yamaha', 'suzuki']\n",
      "['honda', 'yamaha']\n",
      "suzuki\n"
     ]
    }
   ],
   "source": [
    "motorcycles = ['honda', 'yamaha', 'suzuki']\n",
    "print(motorcycles)\n",
    "\n",
    "popped_motorcycle = motorcycles.pop()\n",
    "print(motorcycles)\n",
    "print(popped_motorcycle)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ea5fd9d7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The last motorcycle I owned was a Suzuki.\n"
     ]
    }
   ],
   "source": [
    "motorcycles = ['honda', 'yamaha', 'suzuki']\n",
    "\n",
    "last_owned = motorcycles.pop()\n",
    "print(f\"The last motorcycle I owned was a {last_owned.title()}.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "976b9815",
   "metadata": {},
   "source": [
    "#### (3) 删除列表中任意位置的元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "d67efcd1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['honda', 'yamaha', 'suzuki']\n",
      "['honda', 'suzuki']\n",
      "yamaha\n"
     ]
    }
   ],
   "source": [
    "# 指定索引的pop()\n",
    "# 你可以使用pop()来删除列表中任何位置的元素，只需指定其索引即可。\n",
    "motorcycles = ['honda', 'yamaha', 'suzuki']\n",
    "print(motorcycles)\n",
    "\n",
    "popped_motorcycle = motorcycles.pop(1)\n",
    "print(motorcycles)\n",
    "print(popped_motorcycle)    "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19b3ef44",
   "metadata": {},
   "source": [
    "#### ⚠️ 重要提醒\n",
    "\n",
    "别忘了，每当你使用pop()时，被弹出的元素就不再在列表中了。\n",
    "\n",
    "#### 🤔 选择标准\n",
    "\n",
    "如果不确定该使用del语句还是pop()方法，下面是一个简单的判断标准：\n",
    "\n",
    "- **使用del语句**：如果要从列表中删除一个元素，且不再以任何方式使用它\n",
    "- **使用pop()方法**：如果要在删除元素后继续使用它"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85262b99",
   "metadata": {},
   "source": [
    "### 4.5 根据值删除元素\n",
    "有时候，你不知道要从列表中删除的值在哪个位置。如果只知道要删除的元素的值，可使用remove()方法。\n",
    "\n",
    "remove()方法让Python确定'ducati'出现在列表的什么地方，并将该元素删除。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f91acaf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['honda', 'yamaha', 'suzuki', 'ducati']\n",
      "['honda', 'yamaha', 'suzuki']\n"
     ]
    }
   ],
   "source": [
    "motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati']\n",
    "print(motorcycles)\n",
    "\n",
    "motorcycles.remove('ducati')\n",
    "print(motorcycles)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2def5d5f",
   "metadata": {},
   "source": [
    "使用remove()从列表中删除元素后，也可继续使用它的值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "c7ba70fc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['honda', 'yamaha', 'suzuki', 'ducati']\n",
      "['honda', 'yamaha', 'suzuki']\n",
      "\n",
      "A Ducati is too expensive for me.\n"
     ]
    }
   ],
   "source": [
    "motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati']\n",
    "print(motorcycles)\n",
    "\n",
    "too_expensive = 'ducati'\n",
    "motorcycles.remove(too_expensive)\n",
    "print(motorcycles)\n",
    "print(f\"\\nA {too_expensive.title()} is too expensive for me.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b9cb33ff",
   "metadata": {},
   "source": [
    "**⚠️注意：** remove()方法只删除第一个指定的值。如果要删除的值可能在列表中出现多次，就需要使用循环，确保将每个值都删除。这将在后边讲课中介绍。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba69a519",
   "metadata": {},
   "source": [
    "## 5. 列表操作方法对比\n",
    "\n",
    "| 操作类型             | 方法/语句 | 语法                       | 返回值       | 使用场景           |\n",
    "| -------------------- | --------- | -------------------------- | ------------ | ------------------ |\n",
    "| **访问元素**         | 索引访问  | `list[index]`              | 元素值       | 获取特定位置的元素 |\n",
    "| **修改元素**         | 直接赋值  | `list[index] = new_value`  | 无           | 更改特定位置的元素 |\n",
    "| **添加元素**         | append()  | `list.append(item)`        | 无           | 在末尾添加元素     |\n",
    "| **插入元素**         | insert()  | `list.insert(index, item)` | 无           | 在指定位置插入元素 |\n",
    "| **删除元素(按位置)** | del语句   | `del list[index]`          | 无           | 删除不再使用的元素 |\n",
    "| **删除元素(按位置)** | pop()     | `list.pop(index)`          | 被删除的元素 | 删除并使用该元素   |\n",
    "| **删除元素(按值)**   | remove()  | `list.remove(value)`       | 无           | 根据值删除元素     |\n",
    "\n",
    "## 6. 选择指南\n",
    "### 6.1 何时使用del语句？\n",
    "\n",
    "- ✅ 知道要删除元素的位置\n",
    "- ✅ 删除后不需要使用该元素\n",
    "- ✅ 简单快速的删除操作\n",
    "\n",
    "### 6.2 何时使用pop()方法？\n",
    "\n",
    "- ✅ 知道要删除元素的位置\n",
    "- ✅ 删除后还需要使用该元素\n",
    "- ✅ 实现栈（LIFO）数据结构\n",
    "\n",
    "#### 6.3 何时使用remove()方法？\n",
    "\n",
    "- ✅ 知道要删除元素的值\n",
    "- ✅ 不知道元素的具体位置\n",
    "- ✅ 只需要删除第一个匹配的元素"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f5fb87b",
   "metadata": {},
   "source": [
    "## 💡 7. 最佳实践\n",
    "\n",
    "1. **命名规范**\n",
    "\n",
    " - 使用复数形式命名列表（如：students, cars, names）\n",
    " - 使用有意义的变量名\n",
    "\n",
    "2. **索引使用**\n",
    "\n",
    " - 记住索引从0开始\n",
    " - 使用负数索引访问末尾元素\n",
    " - 注意索引越界错误\n",
    "\n",
    "3. **动态操作**\n",
    "\n",
    " - 优先使用append()构建列表\n",
    " - 根据需求选择合适的删除方法\n",
    " - 考虑操作后是否还需要使用被删除的元素\n",
    "\n",
    "4. **代码可读性**\n",
    "\n",
    " - 在复杂操作前添加注释\n",
    " - 使用有意义的变量名存储pop()的返回值\n",
    " - 保持代码结构清晰\n",
    "\n",
    "## 🚀 8. 进阶提示\n",
    "\n",
    "- 列表是Python中最常用的数据结构之一\n",
    "- 掌握列表操作是学习更高级概念的基础\n",
    "- 在实际项目中，列表操作往往与循环、条件语句结合使用\n",
    "- 理解列表的动态特性对于编写高效程序至关重要"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e86837f1",
   "metadata": {},
   "source": [
    "## 9. 练习\n",
    "### 9.1 基础练习\n",
    "1. 创建一个包含5个朋友姓名的列表\n",
    "2. 使用不同的索引访问并打印每个姓名\n",
    "3. 修改列表中的一个姓名\n",
    "4. 使用三种不同方法添加新朋友到列表中\n",
    "\n",
    "### 9.2 进阶练习\n",
    "\n",
    "1. 创建一个空列表，动态添加10个数字\n",
    "2. 使用三种不同方法删除列表中的元素\n",
    "3. 编写代码处理列表中重复值的删除\n",
    "4. 结合f字符串创建包含列表元素的动态消息"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
